﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Gurucore.Framework.Core;
using Gurucore.Framework.Core.Util;

namespace Gurucore.Framework.DataAccess.Persistence.QueryLanguage
{
	public class Expression : Operand
	{
		private Operand m_oFirstOperand, m_oSecondOperand;
		private Operator m_oOperator;

		protected Expression()
		{
		}

		public Expression(Operand p_oFirstOperand, BinaryOperator p_oOperator, Operand p_oSecondOperand)
		{
			m_oFirstOperand = p_oFirstOperand;
			m_oOperator = p_oOperator;
			m_oSecondOperand = p_oSecondOperand;
		}

		public Expression(Operand p_oFirstOperand, SetOperator p_oOperator, SetOperand p_oSecondOperand)
		{
			m_oFirstOperand = p_oFirstOperand;
			m_oOperator = p_oOperator;
			m_oSecondOperand = p_oSecondOperand;
		}

		public Expression(Operand p_oFirstOperand, RangeOperator p_oOperator, RangeOperand p_oSecondOperand)
		{
			m_oFirstOperand = p_oFirstOperand;
			m_oOperator = p_oOperator;
			m_oSecondOperand = p_oSecondOperand;
		}

		public Expression(PreUnaryOperator p_oOperator, Operand p_oSecondOperand)
		{
			m_oOperator = p_oOperator;
			m_oSecondOperand = p_oSecondOperand;
		}

		public Expression(Operand p_oFirstOperand, PostUnaryOperator p_oOperator)
		{
			m_oFirstOperand = p_oFirstOperand;
			m_oOperator = p_oOperator;
			m_oSecondOperand = new EmptyOperand();
		}

		public static implicit operator Expression(ColumnOperand p_operand)
		{
			return new Expression(PreUnaryOperator.ValueOf, p_operand);
		}

		public static implicit operator Expression(string p_value)
		{
			return new Expression(PreUnaryOperator.ValueOf, new ConstantOperand(p_value));
		}

		public static implicit operator Expression(bool p_value)
		{
			return new Expression(PreUnaryOperator.ValueOf, new ConstantOperand(p_value));
		}

		public static implicit operator Expression(byte p_value)
		{
			return new Expression(PreUnaryOperator.ValueOf, new ConstantOperand(p_value));
		}

		public static implicit operator Expression(int p_value)
		{
			return new Expression(PreUnaryOperator.ValueOf, new ConstantOperand(p_value));
		}

		public static implicit operator Expression(long p_value)
		{
			return new Expression(PreUnaryOperator.ValueOf, new ConstantOperand(p_value));
		}

		public static implicit operator Expression(double p_value)
		{
			return new Expression(PreUnaryOperator.ValueOf, new ConstantOperand(p_value));
		}

		public static implicit operator Expression(DateTime p_value)
		{
			return new Expression(PreUnaryOperator.ValueOf, new ConstantOperand(p_value));
		}

		public static implicit operator Expression(Guid p_value)
		{
			return new Expression(PreUnaryOperator.ValueOf, new ConstantOperand(p_value));
		}

		public override string ToExpressionString(IExpressionMaker p_oExpressionMaker)
		{
			if (m_oOperator.IsUnary())
			{
				if (NullUtil.IsNull(m_oFirstOperand))
				{
					return "(" + m_oOperator.ToString() + " " + m_oSecondOperand.ToExpressionString(p_oExpressionMaker) + ")";
				}
				else
				{
					return "(" + m_oFirstOperand.ToExpressionString(p_oExpressionMaker) + " " + m_oOperator.ToString() + ")";
				}
			}
			else
			{
				return "(" + m_oFirstOperand.ToExpressionString(p_oExpressionMaker) + " " + m_oOperator.ToString() + " " + m_oSecondOperand.ToExpressionString(p_oExpressionMaker) + ")";
			}
		}

		public override string ToString()
		{
			return ToExpressionString(new DefaultExpressionMaker());
		}
	}
}